<template>
  <div class="ssh-terminal">
    <!-- 连接配置面板 -->
    <div v-if="!isConnected" class="connection-panel">
      <el-card>
        <template #header>
          <div class="panel-header">
            <el-icon><Monitor /></el-icon>
            <span>SSH终端连接</span>
          </div>
        </template>
        
        <el-form :model="connectionForm" label-width="100px">
          <el-form-item label="选择主机">
            <el-select 
              v-model="connectionForm.hostId" 
              placeholder="请选择要连接的主机"
              filterable
              style="width: 100%"
            >
              <el-option
                v-for="host in hostList"
                :key="host.id"
                :label="`${host.hostname} (${host.ip})`"
                :value="host.id"
              />
            </el-select>
          </el-form-item>
          
          <el-form-item label="终端大小">
            <el-row :gutter="10">
              <el-col :span="12">
                <el-input-number 
                  v-model="connectionForm.width" 
                  :min="20" 
                  :max="300" 
                  placeholder="宽度"
                />
              </el-col>
              <el-col :span="12">
                <el-input-number 
                  v-model="connectionForm.height" 
                  :min="10" 
                  :max="100" 
                  placeholder="高度"
                />
              </el-col>
            </el-row>
          </el-form-item>
          
          <el-form-item label="终端主题">
            <el-radio-group v-model="connectionForm.theme">
              <el-radio label="dark">深色主题</el-radio>
              <el-radio label="light">浅色主题</el-radio>
            </el-radio-group>
          </el-form-item>
          
          <el-form-item>
            <el-button 
              type="primary" 
              @click="connectSSH" 
              :loading="connecting"
              :disabled="!connectionForm.hostId"
            >
              <el-icon><Connection /></el-icon>
              连接SSH
            </el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </div>

    <!-- 终端界面 -->
    <div v-else class="terminal-container">
      <!-- 工具栏 -->
      <div class="terminal-toolbar">
        <div class="toolbar-left">
          <el-tag :type="getConnectionStatusType()" size="small">
            <el-icon><Monitor /></el-icon>
            {{ connectionStatus }}
          </el-tag>
          <span class="host-info">
            {{ currentHost?.hostname }} ({{ currentHost?.ip }})
          </span>
        </div>
        
        <div class="toolbar-right">
          <el-button-group size="small">
            <el-button @click="clearTerminal">
              <el-icon><Delete /></el-icon>
              清屏
            </el-button>
            <el-button @click="toggleTheme">
              <el-icon><Sunny /></el-icon>
              切换主题
            </el-button>
            <el-button @click="downloadLog">
              <el-icon><Download /></el-icon>
              下载日志
            </el-button>
            <el-button @click="reconnect" :loading="connecting">
              <el-icon><Refresh /></el-icon>
              重连
            </el-button>
            <el-button type="danger" @click="disconnect">
              <el-icon><Close /></el-icon>
              断开
            </el-button>
          </el-button-group>
        </div>
      </div>

      <!-- 终端显示区域 -->
      <div 
        ref="terminalContainer" 
        class="terminal-display"
        :class="{ 'dark-theme': currentTheme === 'dark', 'light-theme': currentTheme === 'light' }"
      ></div>

      <!-- 状态栏 -->
      <div class="terminal-status">
        <div class="status-left">
          <span>会话时长: {{ sessionDuration }}</span>
          <span>发送: {{ formatBytes(bytesSent) }}</span>
          <span>接收: {{ formatBytes(bytesReceived) }}</span>
        </div>
        <div class="status-right">
          <span>{{ terminalSize.width }}x{{ terminalSize.height }}</span>
          <span>{{ currentTheme === 'dark' ? '深色' : '浅色' }}主题</span>
        </div>
      </div>
    </div>

    <!-- 连接状态对话框 -->
    <el-dialog
      v-model="showStatusDialog"
      title="连接状态"
      width="400px"
      :close-on-click-modal="false"
    >
      <div class="status-dialog">
        <el-icon class="status-icon" :class="statusIconClass">
          <component :is="statusIcon" />
        </el-icon>
        <p class="status-message">{{ statusMessage }}</p>
        <div v-if="connecting" class="connecting-progress">
          <el-progress :percentage="connectProgress" :show-text="false" />
          <p>正在建立SSH连接...</p>
        </div>
      </div>
      
      <template #footer>
        <el-button @click="showStatusDialog = false">关闭</el-button>
        <el-button v-if="connectionError" type="primary" @click="retryConnection">
          重试连接
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, nextTick, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { 
  Monitor, Connection, Delete, Sunny, Download, Refresh, Close,
  SuccessFilled, WarningFilled, CircleCloseFilled
} from '@element-plus/icons-vue'
import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import { WebLinksAddon } from 'xterm-addon-web-links'
import 'xterm/css/xterm.css'
import api from '@/utils/api'
import { cmdbApi, SSHWebSocket } from '@/api/monitoring'

// Props
interface Props {
  hostId?: number
  autoConnect?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  autoConnect: false
})

// 响应式数据
const connecting = ref(false)
const isConnected = ref(false)
const connectionStatus = ref('未连接')
const connectionError = ref(false)
const showStatusDialog = ref(false)
const connectProgress = ref(0)

// WebSocket连接
let sshWebSocket: SSHWebSocket | null = null
let terminal: Terminal | null = null
let fitAddon: FitAddon | null = null

// 连接表单
const connectionForm = reactive({
  hostId: props.hostId || null,
  width: 80,
  height: 24,
  theme: 'dark'
})

// 主机列表
const hostList = ref([])
const currentHost = ref(null)
const currentTheme = ref('dark')

// 终端状态
const terminalContainer = ref<HTMLElement>()
const sessionStartTime = ref<Date | null>(null)
const sessionDuration = ref('00:00:00')
const bytesSent = ref(0)
const bytesReceived = ref(0)
const terminalSize = reactive({ width: 80, height: 24 })

// 状态对话框
const statusMessage = ref('')
const statusIcon = ref('Monitor')
const statusIconClass = ref('')

// 计算属性
const getConnectionStatusType = () => {
  switch (connectionStatus.value) {
    case '已连接': return 'success'
    case '连接中': return 'warning'
    case '连接失败': return 'danger'
    default: return 'info'
  }
}

// 获取主机列表
const fetchHostList = async () => {
  try {
    const response = await cmdbApi.getHosts()
    if (response.data.success) {
      hostList.value = response.data.data.results || response.data.data
    }
  } catch (error) {
    console.error('获取主机列表失败:', error)
    ElMessage.error('获取主机列表失败')
  }
}

// 连接SSH
const connectSSH = async () => {
  if (!connectionForm.hostId) {
    ElMessage.warning('请选择要连接的主机')
    return
  }

  connecting.value = true
  connectionError.value = false
  showStatusDialog.value = true
  statusMessage.value = '正在建立连接...'
  statusIcon.value = 'Monitor'
  statusIconClass.value = 'connecting'
  connectProgress.value = 0

  try {
    // 获取主机信息
    currentHost.value = hostList.value.find(host => host.id === connectionForm.hostId)
    
    // 初始化终端
    await initTerminal()
    
    // 建立WebSocket连接
    await connectWebSocket()
    
  } catch (error) {
    console.error('SSH连接失败:', error)
    connectionError.value = true
    statusMessage.value = `连接失败: ${error.message}`
    statusIcon.value = 'CircleCloseFilled'
    statusIconClass.value = 'error'
  } finally {
    connecting.value = false
  }
}

// 初始化终端
const initTerminal = async () => {
  await nextTick()
  
  if (!terminalContainer.value) {
    throw new Error('终端容器未找到')
  }

  // 创建终端实例
  terminal = new Terminal({
    cols: connectionForm.width,
    rows: connectionForm.height,
    theme: getTerminalTheme(connectionForm.theme),
    fontSize: 14,
    fontFamily: 'Monaco, Consolas, "Courier New", monospace',
    cursorBlink: true,
    cursorStyle: 'block',
    scrollback: 1000,
    tabStopWidth: 4
  })

  // 添加插件
  fitAddon = new FitAddon()
  terminal.loadAddon(fitAddon)
  terminal.loadAddon(new WebLinksAddon())

  // 打开终端
  terminal.open(terminalContainer.value)
  fitAddon.fit()

  // 更新终端大小
  terminalSize.width = terminal.cols
  terminalSize.height = terminal.rows

  // 监听终端输入
  terminal.onData((data) => {
    if (sshWebSocket && sshWebSocket.readyState === WebSocket.OPEN) {
      sshWebSocket.send({
        type: 'ssh_input',
        data: data
      })
    }
  })

  // 监听终端大小变化
  terminal.onResize((size) => {
    terminalSize.width = size.cols
    terminalSize.height = size.rows

    if (sshWebSocket && sshWebSocket.readyState === WebSocket.OPEN) {
      sshWebSocket.send({
        type: 'ssh_resize',
        width: size.cols,
        height: size.rows
      })
    }
  })

  isConnected.value = true
}

// 建立WebSocket连接
const connectWebSocket = () => {
  return new Promise((resolve, reject) => {
    sshWebSocket = new SSHWebSocket(connectionForm.hostId)

    sshWebSocket.connect({
      onOpen: () => {
        connectProgress.value = 50
        statusMessage.value = '正在建立SSH连接...'

        // 发送连接请求
        sshWebSocket.send({
          type: 'ssh_connect',
          width: connectionForm.width,
          height: connectionForm.height
        })
      },

      onMessage: (data) => {
        handleWebSocketMessage(data)

        if (data.type === 'status' && data.status === 'connected') {
          connectProgress.value = 100
          connectionStatus.value = '已连接'
          statusMessage.value = 'SSH连接成功'
          statusIcon.value = 'SuccessFilled'
          statusIconClass.value = 'success'
          sessionStartTime.value = new Date()
          startSessionTimer()

          setTimeout(() => {
            showStatusDialog.value = false
          }, 1500)

          resolve(true)
        }
      },

      onError: (error) => {
        console.error('WebSocket错误:', error)
        reject(new Error('WebSocket连接失败'))
      },

      onClose: () => {
        connectionStatus.value = '连接已断开'
        isConnected.value = false
        stopSessionTimer()
      }
    })

    // 连接超时处理
    setTimeout(() => {
      if (sshWebSocket.readyState !== WebSocket.OPEN) {
        reject(new Error('连接超时'))
      }
    }, 10000)
  })
}

// 处理WebSocket消息
const handleWebSocketMessage = (data: any) => {
  switch (data.type) {
    case 'ssh_output':
      if (terminal) {
        terminal.write(data.data)
        bytesReceived.value += data.data.length
      }
      break
    case 'status':
      connectionStatus.value = data.message
      break
    case 'error':
      ElMessage.error(data.message)
      connectionError.value = true
      break
  }
}

// 获取终端主题
const getTerminalTheme = (theme: string) => {
  if (theme === 'light') {
    return {
      background: '#ffffff',
      foreground: '#000000',
      cursor: '#000000',
      selection: '#b3d4fc'
    }
  } else {
    return {
      background: '#1e1e1e',
      foreground: '#ffffff',
      cursor: '#ffffff',
      selection: '#264f78'
    }
  }
}

// 工具函数
const formatBytes = (bytes: number) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const startSessionTimer = () => {
  setInterval(() => {
    if (sessionStartTime.value) {
      const now = new Date()
      const diff = now.getTime() - sessionStartTime.value.getTime()
      const hours = Math.floor(diff / 3600000)
      const minutes = Math.floor((diff % 3600000) / 60000)
      const seconds = Math.floor((diff % 60000) / 1000)
      sessionDuration.value = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
    }
  }, 1000)
}

const stopSessionTimer = () => {
  // 停止计时器的逻辑
}

// 终端操作
const clearTerminal = () => {
  if (terminal) {
    terminal.clear()
  }
}

const toggleTheme = () => {
  currentTheme.value = currentTheme.value === 'dark' ? 'light' : 'dark'
  if (terminal) {
    terminal.options.theme = getTerminalTheme(currentTheme.value)
  }
}

const downloadLog = () => {
  ElMessage.info('下载日志功能开发中')
}

const reconnect = () => {
  disconnect()
  setTimeout(() => {
    connectSSH()
  }, 1000)
}

const disconnect = () => {
  if (sshWebSocket) {
    sshWebSocket.send({ type: 'ssh_disconnect' })
    sshWebSocket.close()
  }

  if (terminal) {
    terminal.dispose()
    terminal = null
  }

  isConnected.value = false
  connectionStatus.value = '未连接'
  stopSessionTimer()
}

const retryConnection = () => {
  showStatusDialog.value = false
  connectSSH()
}

// 生命周期
onMounted(() => {
  fetchHostList()
  
  if (props.autoConnect && props.hostId) {
    connectSSH()
  }
})

onUnmounted(() => {
  disconnect()
})
</script>

<style scoped>
.ssh-terminal {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.connection-panel {
  max-width: 600px;
  margin: 50px auto;
}

.panel-header {
  display: flex;
  align-items: center;
  gap: 8px;
}

.terminal-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  height: 100%;
}

.terminal-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  background: #f5f5f5;
  border-bottom: 1px solid #e0e0e0;
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 15px;
}

.host-info {
  font-size: 14px;
  color: #606266;
}

.terminal-display {
  flex: 1;
  padding: 0;
  overflow: hidden;
}

.terminal-display.dark-theme {
  background: #1e1e1e;
}

.terminal-display.light-theme {
  background: #ffffff;
}

.terminal-status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 15px;
  background: #f0f0f0;
  border-top: 1px solid #e0e0e0;
  font-size: 12px;
  color: #666;
}

.status-left,
.status-right {
  display: flex;
  gap: 15px;
}

.status-dialog {
  text-align: center;
  padding: 20px;
}

.status-icon {
  font-size: 48px;
  margin-bottom: 15px;
}

.status-icon.connecting {
  color: #409EFF;
}

.status-icon.success {
  color: #67C23A;
}

.status-icon.error {
  color: #F56C6C;
}

.status-message {
  font-size: 16px;
  margin-bottom: 15px;
}

.connecting-progress {
  margin-top: 20px;
}

.connecting-progress p {
  margin-top: 10px;
  font-size: 14px;
  color: #666;
}
</style>
